package com.ruoyi.common.utils.file;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.ruoyi.common.config.AliyunOSSConfig;
import com.ruoyi.common.exception.ServiceException;

/**
 * 阿里云OSS文件上传工具类
 * 
 * @author ruoyi
 */
@Component
public class AliyunOSSUtils
{
    @Autowired
    private AliyunOSSConfig ossConfig;

    /**
     * 上传文件到阿里云OSS
     * 
     * @param file 上传的文件
     * @return 文件访问URL
     */
    public String upload(MultipartFile file) throws IOException
    {
        // 检查OSS是否启用
        if (!ossConfig.getEnabled())
        {
            throw new ServiceException("OSS未启用，请检查配置");
        }

        // 获取文件原始名称
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null || originalFilename.isEmpty())
        {
            throw new ServiceException("文件名不能为空");
        }

        // 生成文件名：prefix + 日期 + UUID + 扩展名
        String fileName = generateFileName(originalFilename);

        // 创建OSS客户端
        OSS ossClient = new OSSClientBuilder().build(
            ossConfig.getEndpoint(),
            ossConfig.getAccessKeyId(),
            ossConfig.getAccessKeySecret()
        );

        try
        {
            // 上传文件流
            InputStream inputStream = file.getInputStream();
            ossClient.putObject(ossConfig.getBucketName(), fileName, inputStream);

            // 返回文件访问URL
            return getFileUrl(fileName);
        }
        catch (Exception e)
        {
            throw new ServiceException("文件上传失败：" + e.getMessage());
        }
        finally
        {
            // 关闭OSS客户端
            if (ossClient != null)
            {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 上传字节数组到阿里云OSS
     * 
     * @param bytes 文件字节数组
     * @param originalFilename 原始文件名
     * @return 文件访问URL
     */
    public String upload(byte[] bytes, String originalFilename)
    {
        // 检查OSS是否启用
        if (!ossConfig.getEnabled())
        {
            throw new ServiceException("OSS未启用，请检查配置");
        }

        // 生成文件名
        String fileName = generateFileName(originalFilename);

        // 创建OSS客户端
        OSS ossClient = new OSSClientBuilder().build(
            ossConfig.getEndpoint(),
            ossConfig.getAccessKeyId(),
            ossConfig.getAccessKeySecret()
        );

        try
        {
            // 上传字节数组
            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
            ossClient.putObject(ossConfig.getBucketName(), fileName, inputStream);

            // 返回文件访问URL
            return getFileUrl(fileName);
        }
        catch (Exception e)
        {
            throw new ServiceException("文件上传失败：" + e.getMessage());
        }
        finally
        {
            // 关闭OSS客户端
            if (ossClient != null)
            {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 上传文件流到阿里云OSS（指定文件路径）
     * 
     * @param ossPath OSS文件路径（如：qrcode/merchant_8.png）
     * @param inputStream 文件输入流
     * @return 文件访问URL
     */
    public String uploadFile(String ossPath, InputStream inputStream)
    {
        // 检查OSS是否启用
        if (!ossConfig.getEnabled())
        {
            throw new ServiceException("OSS未启用，请检查配置");
        }

        // 创建OSS客户端
        OSS ossClient = new OSSClientBuilder().build(
            ossConfig.getEndpoint(),
            ossConfig.getAccessKeyId(),
            ossConfig.getAccessKeySecret()
        );

        try
        {
            // 上传文件流
            ossClient.putObject(ossConfig.getBucketName(), ossPath, inputStream);

            // 返回文件访问URL
            return getFileUrl(ossPath);
        }
        catch (Exception e)
        {
            throw new ServiceException("文件上传失败：" + e.getMessage());
        }
        finally
        {
            // 关闭OSS客户端
            if (ossClient != null)
            {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 删除OSS文件
     * 
     * @param fileName 文件名
     */
    public void delete(String fileName)
    {
        if (!ossConfig.getEnabled())
        {
            return;
        }

        OSS ossClient = new OSSClientBuilder().build(
            ossConfig.getEndpoint(),
            ossConfig.getAccessKeyId(),
            ossConfig.getAccessKeySecret()
        );

        try
        {
            ossClient.deleteObject(ossConfig.getBucketName(), fileName);
        }
        finally
        {
            if (ossClient != null)
            {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 生成文件名：prefix/yyyy/MM/dd/uuid.ext
     * 
     * @param originalFilename 原始文件名
     * @return 生成的文件名
     */
    private String generateFileName(String originalFilename)
    {
        // 获取文件扩展名
        String extension = "";
        int dotIndex = originalFilename.lastIndexOf(".");
        if (dotIndex > 0)
        {
            extension = originalFilename.substring(dotIndex);
        }

        // 生成日期路径：yyyy/MM/dd
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        String datePath = sdf.format(new Date());

        // 生成UUID
        String uuid = UUID.randomUUID().toString().replace("-", "");

        // 拼接文件名：prefix/yyyy/MM/dd/uuid.ext
        String prefix = ossConfig.getPrefix();
        if (prefix == null || prefix.isEmpty())
        {
            prefix = "";
        }
        else if (!prefix.endsWith("/"))
        {
            prefix += "/";
        }

        return prefix + datePath + "/" + uuid + extension;
    }

    /**
     * 获取文件访问URL
     * 
     * @param fileName 文件名
     * @return 文件访问URL
     */
    private String getFileUrl(String fileName)
    {
        // 如果配置了自定义域名，使用自定义域名
        if (ossConfig.getDomain() != null && !ossConfig.getDomain().isEmpty())
        {
            String domain = ossConfig.getDomain();
            if (!domain.endsWith("/"))
            {
                domain += "/";
            }
            return domain + fileName;
        }

        // 否则使用OSS默认域名
        return "https://" + ossConfig.getBucketName() + "." + ossConfig.getEndpoint() + "/" + fileName;
    }
}

